java单一责任原则与服务/存储库设计
我想知道如何在下面的例子中最好地分离责任
有一个Foo
对象,它有一些id
和一些reallySecretImportantData
字段。Id是引用对象的简单标识符,而reallySecretImportantData
是数据库中应该加密的数据,因为在本例中,数据库是唯一易受攻击的点
现在,如果我们有一个FooService
方法void storeFoo(Foo foo)
和Foo readFoo(Id id)
我们还有一个FooRepository
,它有标准的CRUD方法,在数据库中存储Foo对象
现在,由于我想保存reallySecretImportantData
加密,我必须在某处加密并解密它
由于FooRepository
的职责不应包括加密操作,因此逻辑位置为FooService
现在,如果我在某个开发环境中,我希望,对于dev&;测试目的是将reallySecretImportantData
保存为纯文本
如果我使用某种DI,我可以编写我的服务的两个实现,一个用于prod,另一个用于dev/test,只需将DI配置为在生产环境中使用prod,在dev&;中使用dev/test;测试环境
现在,如果在不久的将来出现更改reallySecretImportantData
存储方式的请求,我可以简单地编写服务的另一个实现,并使用我的DI框架注入它
这种简单的设计对于当前的模型箱来说足够好吗
# 1 楼答案
你的设计让我想起strategy pattern.
FooService
可以被视为一个策略接口但是我更喜欢向这个接口添加
encrypt()
和decrypt()
方法,而不是store()
和read()
。我们可以把它命名为FooCryptoStrategy
此外,
FooRepository
可以用FooCryptoStrategy
对象构造。 因此,您可以不考虑加密问题而对Foo
对象进行CRUD。 您可以为发布和测试创建几个FooCryptoStrategy
实现。甚至你也可以实现一个NonCryptoStrategy
总之,使用策略模式,我们可以将一个职责分配给一个类:
Foo
:存储数据FooCryptoStrategy
:加密和解密Foo
对象FooRepository
:使Foo对象持久化控制器类:创建具体的
FooCryptoStrategy
和FooRepository
对象# 2 楼答案
你为什么需要“服务”
考虑一个知道如何En/De/Curpt的^ {< CD1>}对象,以及一个处理持久性的数据管理对象。
通过使用一个通用接口实现加密算法,使您的功能“可插拔”,例如IcenRypt。例如,你可能有一个AES加密机和一个TestPlainEncryptor